#encoding: utf-8

import os
import sys
import unittest
import api


DIR = 'archivos_test'
cero_por_uno = 'Tendría que devolver 0 y devuelve 1'
uno_por_cero = 'Tendría que devolver 1 y devuelve 0'
no_carga_lados = 'No carga bien los lados'
no_carga_valor = 'No actualiza correctamente el valor del flujo'
no_carga_flujo = 'No actualiza correctamente los lados del flujo'


class EKTest(unittest.TestCase):
    def testa_leer_un_lado_simple_ok(self):
        """Prueba si la función leer_un_lado con una sola linea"""
        f = file(DIR + '/una_linea', 'r')
        d = {4: {5: 6}}
        stdin_original = sys.stdin
        sys.stdin = f
        objetoEK = api.EstadoEK(0)
        self.assertEqual(objetoEK.leer_un_lado(), 1, cero_por_uno)
        self.assertEqual(objetoEK.matriz, d, no_carga_lados)
        sys.stdin = stdin_original
        f.close()

    def testb_leer_un_lado_simple_nok(self):
        """Prueba si la función leer un lado parsea correctamente si hay
        elementos no enteros."""
        f = file('prueba1', 'w+r')
        f.write('3 a 9\n')
        stdin_original = sys.stdin
        sys.stdin = f
        objetoEK = api.EstadoEK(0)
        self.assertEqual(objetoEK.leer_un_lado(), 0, uno_por_cero)
        self.assertEqual(objetoEK.matriz, {}, no_carga_lados)
        sys.stdin = stdin_original
        f.close()

    def testc_leer_un_lado_ok(self):
        """Prueba que leer un lado funcione correctamente con varias líneas,
        aunque lea una sola"""
        f = file(DIR + '/network_7iii_result10', 'r')
        d = {0: {2: 4}}
        stdin_original = sys.stdin
        sys.stdin = f
        objetoEK = api.EstadoEK(0)
        self.assertEqual(objetoEK.leer_un_lado(), 1, cero_por_uno)
        self.assertEqual(objetoEK.matriz, d, no_carga_lados)
        sys.stdin = stdin_original
        f.close()

    def testd_leer_un_lado_completo_ok(self):
        """Prueba que leer un lado funcione correctamente con varias líneas"""
        f = file(DIR + '/network_4lados_result6', 'r')
        d = {0: {2: 3, 3: 4}, 2: {1: 9}, 3: {1: 8}}
        stdin_original = sys.stdin
        sys.stdin = f
        objetoEK = api.EstadoEK(0)
        while objetoEK.leer_un_lado() == 1:
            pass
        self.assertEqual(objetoEK.matriz, d, no_carga_lados)
        sys.stdin = stdin_original
        f.close()

    def teste_aumentar_flujo_ok(self):
        """Controla aumentar_flujo de un solo lado"""
        f = file(DIR + '/network_4lados_result6', 'r')
        fo = file(DIR + '/salida_teste', 'w')
        stdin_original = sys.stdin
        sys.stdin = f
        stdout_original = sys.stdout
        sys.stdout = fo
        objetoEK = api.EstadoEK(111)
        while objetoEK.leer_un_lado() == 1:  # Leemos todos los lados
            pass
        self.assertEqual(objetoEK.aumentar_flujo(), 1, cero_por_uno)
        d = {0: {2: 0, 3: 4}, 2: {1: 6}, 3: {1: 8}}
        self.assertEqual(objetoEK.flujo.flujo_max, 3, no_carga_valor)
        self.assertEqual(objetoEK.flujo.lados, d, no_carga_flujo)

        self.assertEqual(objetoEK.aumentar_flujo(), 1, cero_por_uno)
        d = {0: {2: 0, 3: 0}, 2: {1: 6}, 3: {1: 4}}
        self.assertEqual(objetoEK.flujo.flujo_max, 7, no_carga_valor)
        self.assertEqual(objetoEK.flujo.lados, d, no_carga_flujo)

        self.assertEqual(objetoEK.aumentar_flujo(), 0, uno_por_cero)
        self.assertEqual(objetoEK.flujo.flujo_max, 7, no_carga_valor)
        self.assertEqual(objetoEK.flujo.lados, d, no_carga_flujo)

        sys.stdin = stdin_original
        f.close()
        sys.stdout = stdout_original
        fo.close()

    def testf_aumentar_flujo_completook(self):
        f = file(DIR + '/network_7iii_result10', 'r')
        fo = file(DIR + '/salida_testf', 'w')
        stdin_original = sys.stdin
        sys.stdin = f
        stdout_original = sys.stdout
        sys.stdout = fo
        objetoEK = api.EstadoEK(112)
        while objetoEK.leer_un_lado() == 1:  # Leemos todos los lados
            pass
        while objetoEK.aumentar_flujo() == 1:  # Aumentamos el flujo
            pass

        self.assertEqual(objetoEK.flujo.flujo_max, 10, no_carga_valor)

        sys.stdin = stdin_original
        f.close()
        sys.stdout = stdout_original
        fo.close()

    def testg_aumentar_flujo_completook(self):
        f = file(DIR + '/penazzi2_result512', 'r')
        fo = file(DIR + '/salida_testg', 'w')
        stdin_original = sys.stdin
        sys.stdin = f
        stdout_original = sys.stdout
        sys.stdout = fo
        objetoEK = api.EstadoEK(1)
        inicio = os.times()
        while objetoEK.leer_un_lado() == 1:  # Leemos todos los lados
            pass
        while objetoEK.aumentar_flujo() == 1:  # Aumentamos el flujo
            pass
        fin = os.times()
        self.assertEqual(objetoEK.flujo.flujo_max, 512, no_carga_valor)
        print '-----------------------------------'
        print 'Tiempo : ' + str(fin[4] - inicio[4])
        sys.stdin = stdin_original
        f.close()
        sys.stdout = stdout_original
        fo.close()

    def testh_aumentar_flujo_completook(self):
        f = file(DIR + '/penazzi_result512', 'r')
        fo = file(DIR + '/salida_testh', 'w')
        stdin_original = sys.stdin
        sys.stdin = f
        stdout_original = sys.stdout
        sys.stdout = fo
        objetoEK = api.EstadoEK(1)
        inicio = os.times()
        while objetoEK.leer_un_lado() == 1:  # Leemos todos los lados
            pass
        while objetoEK.aumentar_flujo() == 1:  # Aumentamos el flujo
            pass
        fin = os.times()
        self.assertEqual(objetoEK.flujo.flujo_max, 512, no_carga_valor)
        print '-----------------------------------'
        print 'Tiempo : ' + str(fin[4] - inicio[4])
        sys.stdin = stdin_original
        f.close()
        sys.stdout = stdout_original
        fo.close()

    def testi_aumentar_flujo_completook(self):
        f = file(DIR + '/penazzi3_result512', 'r')
        fo = file(DIR + '/salida_testi', 'w')
        stdin_original = sys.stdin
        sys.stdin = f
        stdout_original = sys.stdout
        sys.stdout = fo
        objetoEK = api.EstadoEK(1)
        inicio = os.times()
        while objetoEK.leer_un_lado() == 1:  # Leemos todos los lados
            pass
        while objetoEK.aumentar_flujo() == 1:  # Aumentamos el flujo
            pass
        fin = os.times()
        self.assertEqual(objetoEK.flujo.flujo_max, 512, no_carga_valor)
        print '-----------------------------------'
        print 'Tiempo : ' + str(fin[4] - inicio[4])
        sys.stdin = stdin_original
        f.close()
        sys.stdout = stdout_original
        fo.close()


if __name__ == '__main__':
    unittest.main()
